home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Serial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  39.0 KB  |  2,124 lines

  1. /*
  2. **    Serial.c
  3. **
  4. **    Serial driver support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Local copy of serial driver name and unit number. */
  17.  
  18. STATIC UBYTE    SerialDevice[40];
  19. STATIC LONG    UnitNumber = -1;
  20.  
  21. STATIC BOOLEAN    SerialLocked;
  22.  
  23.     /* SetFlags():
  24.      *
  25.      *    Set the contents of a serial device request according
  26.      *    to the current configuration settings.
  27.      */
  28.  
  29. STATIC BYTE
  30. SetFlags(VOID)
  31. {
  32.     return(SetBothSerialAttributes(
  33.         SERA_Baud,            Config -> SerialConfig -> BaudRate,
  34.         SERA_BreakTime,        Config -> SerialConfig -> BreakLength,
  35.         SERA_BitsPerChar,    Config -> SerialConfig -> BitsPerChar,
  36.         SERA_StopBits,        Config -> SerialConfig -> StopBits,
  37.         SERA_BufferSize,    Config -> SerialConfig -> SerialBufferSize,
  38.         SERA_Parity,        Config -> SerialConfig -> Parity,
  39.         SERA_Handshaking,    UseRTS_CTS ? Config -> SerialConfig -> HandshakingProtocol : HANDSHAKING_NONE,
  40.         SERA_HighSpeed,        Config -> SerialConfig -> HighSpeed,
  41.         SERA_Shared,        Config -> SerialConfig -> Shared,
  42.     TAG_DONE));
  43. }
  44.  
  45.     /* SendBreak():
  46.      *
  47.      *    Transmit a break signal.
  48.      */
  49.  
  50. VOID
  51. SendBreak()
  52. {
  53.     BYTE OldStatus = Status;
  54.  
  55.     Status = STATUS_BREAKING;
  56.  
  57.     DoSerialCmd(SDCMD_BREAK);
  58.  
  59.     Status = OldStatus;
  60. }
  61.  
  62.     /* HangUp():
  63.      *
  64.      *    Hang up the line.
  65.      */
  66.  
  67. VOID
  68. HangUp()
  69. {
  70.     BYTE OldStatus = Status;
  71.  
  72.     StopSerialWrite();
  73.  
  74.     Status = STATUS_HANGUP;
  75.  
  76.         /* Are we to drop the DTR line
  77.          * before sending the hangup
  78.          * string?
  79.          */
  80.  
  81.     if(Config -> ModemConfig -> DropDTR && WriteRequest)
  82.     {
  83.         /* Let's be nice and try to transmit the
  84.          * `drop the line' command before
  85.          * trying to close and reopen the driver.
  86.          */
  87.  
  88.         WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  89.         WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  90.         WriteRequest -> IOSer . io_Length    = 0;
  91.  
  92.             /* Transmit the command. */
  93.  
  94.         if(!DoIO(WriteRequest))
  95.         {
  96.                 /* Wait a bit... */
  97.  
  98.             DelayTime(1,0);
  99.  
  100.                 /* Raise the line again. */
  101.  
  102.             WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  103.             WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  104.             WriteRequest -> IOSer . io_Length    = SIOB_DTRF;
  105.  
  106.             DoIO(WriteRequest);
  107.         }
  108.         else
  109.         {
  110.                 /* Do it the standard way: close and reopen
  111.                  * the serial driver (the serial.device is
  112.                  * supposed to drop the DTR line when closed).
  113.                  */
  114.  
  115.             if(!DropDTR())
  116.             {
  117.                 if(!ShowRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_REOPEN_UNIT_TXT),LocaleString(MSG_TERMMAIN_IGNORE_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  118.                     MainTerminated = TRUE;
  119.             }
  120.         }
  121.     }
  122.  
  123.         /* Transmit the hangup command. */
  124.  
  125.     if(Config -> ModemConfig -> ModemHangup[0])
  126.         SerialCommand(Config -> ModemConfig -> ModemHangup);
  127.  
  128.         /* Reset to old status. */
  129.  
  130.     Status = OldStatus;
  131. }
  132.  
  133.     /* DropDTR():
  134.      *
  135.      *    Drop the data terminal ready signal (i.e. close, wait a bit
  136.      *    and then reopen the serial drive).
  137.      */
  138.  
  139. BOOL
  140. DropDTR()
  141. {
  142.         /* Finish all serial read activity. */
  143.  
  144.     ClearSerial();
  145.  
  146.         /* Do we have any channels to work with? */
  147.  
  148.     if(ReadRequest && WriteRequest)
  149.     {
  150.             /* Close the device. */
  151.  
  152.         CloseDevice(ReadRequest);
  153.  
  154.             /* Wait a bit. */
  155.  
  156.         DelayTime(1,0);
  157.  
  158.             /* Reopen the driver. */
  159.  
  160.         if(!OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0))
  161.         {
  162.             struct MsgPort *WritePort = WriteRequest -> IOSer . io_Message . mn_ReplyPort;
  163.  
  164.             ResetSerialRead();
  165.             ResetSerialWrite();
  166.  
  167.                 /* Fill in the rest. */
  168.  
  169.             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  170.  
  171.             WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  172.  
  173.             SetFlags();
  174.  
  175.             DoSerialCmd(SDCMD_SETPARAMS);
  176.  
  177.                 /* Restart read activity. */
  178.  
  179.             RestartSerial();
  180.  
  181.             return(TRUE);
  182.         }
  183.         else
  184.             DeleteSerial();
  185.     }
  186.     else
  187.     {
  188.         DeleteSerial();
  189.  
  190.         return(TRUE);
  191.     }
  192.  
  193.     return(FALSE);
  194. }
  195.  
  196.     /* CopyWriteFlags():
  197.      *
  198.      *    Update configuration with serial settings.
  199.      */
  200.  
  201. VOID
  202. CopyWriteFlags()
  203. {
  204.     ULONG    Baud,
  205.             BreakTime,
  206.             BitsPerChar,
  207.             StopBits,
  208.             BufferSize,
  209.             Parity,
  210.             Handshaking,
  211.             HighSpeed,
  212.             Shared;
  213.  
  214.     GetSerialWriteAttributes(
  215.         SERA_Baud,            &Baud,
  216.         SERA_BreakTime,        &BreakTime,
  217.         SERA_BitsPerChar,    &BitsPerChar,
  218.         SERA_StopBits,        &StopBits,
  219.         SERA_BufferSize,    &BufferSize,
  220.         SERA_Parity,        &Parity,
  221.         SERA_Handshaking,    &Handshaking,
  222.         SERA_HighSpeed,        &HighSpeed,
  223.         SERA_Shared,        &Shared,
  224.     TAG_DONE);
  225.  
  226.     Config -> SerialConfig -> BaudRate                = Baud;
  227.     Config -> SerialConfig -> BreakLength            = BreakTime;
  228.     Config -> SerialConfig -> BitsPerChar            = BitsPerChar;
  229.     Config -> SerialConfig -> StopBits                = StopBits;
  230.     Config -> SerialConfig -> SerialBufferSize        = BufferSize;
  231.     Config -> SerialConfig -> Parity                = Parity;
  232.     Config -> SerialConfig -> HandshakingProtocol    = Handshaking;
  233.     Config -> SerialConfig -> HighSpeed                = HighSpeed;
  234.     Config -> SerialConfig -> Shared                = Shared;
  235. }
  236.  
  237.     /* CallMenu(STRPTR Name,ULONG Code):
  238.      *
  239.      *    Call a menu function either through the name of the corresponding
  240.      *    menu item or a menu number.
  241.      */
  242.  
  243. STATIC VOID
  244. CallMenu(STRPTR Name,ULONG Code)
  245. {
  246.     LONG MenuNum = -1,Item = 0,Sub = 0,i;
  247.  
  248.         /* Are we to look for a name? */
  249.  
  250.     if(Name)
  251.     {
  252.         LONG Len = strlen(Name);
  253.  
  254.             /* Scan the menu list... */
  255.  
  256.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  257.         {
  258.             switch(TermMenu[i] . nm_Type)
  259.             {
  260.                 case NM_TITLE:
  261.  
  262.                     MenuNum++;
  263.                     Item = Sub = 0;
  264.                     break;
  265.  
  266.                 case NM_ITEM:
  267.  
  268.                     Sub = 0;
  269.                     break;
  270.             }
  271.  
  272.                 /* Did we get a valid name string? */
  273.  
  274.             if(TermMenu[i] . nm_Label != NM_BARLABEL)
  275.             {
  276.                     /* Does the name match our template? */
  277.  
  278.                 if(!Strnicmp(TermMenu[i] . nm_Label,Name,Len))
  279.                 {
  280.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  281.  
  282.                     if(MenuItem && (MenuItem -> Flags & ITEMENABLED))
  283.                         HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  284.  
  285.                     break;
  286.                 }
  287.             }
  288.  
  289.             switch(TermMenu[i] . nm_Type)
  290.             {
  291.                 case NM_ITEM:
  292.  
  293.                     Item++;
  294.                     break;
  295.  
  296.                 case NM_SUB:
  297.  
  298.                     Sub++;
  299.                     break;
  300.             }
  301.         }
  302.     }
  303.     else
  304.     {
  305.         LONG    TheMenu    =  Code % 100,
  306.                 TheItem    = (Code / 100) % 100,
  307.                 TheSub    =  Code / 10000;
  308.  
  309.             /* Scan the menu list... */
  310.  
  311.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  312.         {
  313.             switch(TermMenu[i] . nm_Type)
  314.             {
  315.                 case NM_TITLE:
  316.  
  317.                     MenuNum++;
  318.                     Item = Sub = 0;
  319.                     break;
  320.  
  321.                 case NM_ITEM:
  322.  
  323.                     Sub = 0;
  324.                     break;
  325.             }
  326.  
  327.                 /* Is it the menu number we want? */
  328.  
  329.             if(TheMenu == MenuNum && TheItem == Item && TheSub == Sub)
  330.             {
  331.                 if(TermMenu[i] . nm_Label != NM_BARLABEL)
  332.                 {
  333.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  334.  
  335.                     if(MenuItem && (MenuItem -> Flags & ITEMENABLED))
  336.                         HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  337.                 }
  338.  
  339.                 break;
  340.             }
  341.  
  342.             switch(TermMenu[i] . nm_Type)
  343.             {
  344.                 case NM_ITEM:
  345.  
  346.                     Item++;
  347.                     break;
  348.  
  349.                 case NM_SUB:
  350.  
  351.                     Sub++;
  352.                     break;
  353.             }
  354.         }
  355.     }
  356. }
  357.  
  358.     /* SerialCommand(STRPTR String):
  359.      *
  360.      *    Send a command string to the serial line and
  361.      *    interprete the control sequences.
  362.      */
  363.  
  364. VOID
  365. SerialCommand(STRPTR String)
  366. {
  367.     BOOL    (* SendLineLocal)(register STRPTR,register LONG);
  368.  
  369.     LONG    Count = 0,i,Len = strlen(String);
  370.  
  371.     BOOL    GotControl    = FALSE,
  372.             GotEscape    = FALSE;
  373.  
  374.     SendLineLocal = SendLine;
  375.  
  376.         /* Scan the string. */
  377.  
  378.     for(i = 0 ; i < Len ; i++)
  379.     {
  380.             /* We are looking for plain characters
  381.              * and the control ('\') and escape
  382.              * ('^') characters.
  383.              */
  384.  
  385.         if(!GotControl && !GotEscape)
  386.         {
  387.                 /* Got a control character,
  388.                  * the next byte will probably be
  389.                  * a command sequence.
  390.                  */
  391.  
  392.             if(String[i] == '\\')
  393.             {
  394.                 GotControl = TRUE;
  395.                 continue;
  396.             }
  397.  
  398.                 /* Got an escape character,
  399.                  * the next byte will be some
  400.                  * kind of control character
  401.                  * (such as XON, XOF, bell, etc.).
  402.                  */
  403.  
  404.             if(String[i] == '^')
  405.             {
  406.                 GotEscape = TRUE;
  407.                 continue;
  408.             }
  409.  
  410.                 /* This tells us to wait another
  411.                  * second before continuing with
  412.                  * the scanning.
  413.                  */
  414.  
  415.             if(String[i] == '~')
  416.             {
  417.                 if(Count)
  418.                 {
  419.                     (*SendLineLocal)(SharedBuffer,Count);
  420.  
  421.                     Count = 0;
  422.                 }
  423.  
  424.                 DelayTime(0,MILLION / 2);
  425.  
  426.                 HandleSerial();
  427.  
  428.                 continue;
  429.             }
  430.  
  431.                 /* Stuff the character into the
  432.                  * buffer.
  433.                  */
  434.  
  435.             SharedBuffer[Count++] = String[i];
  436.         }
  437.         else
  438.         {
  439.                 /* Convert the character to a control
  440.                  * style character (^C, etc.).
  441.                  */
  442.  
  443.             if(GotEscape)
  444.             {
  445.                 if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= '_')
  446.                     SharedBuffer[Count++] = ToUpper(String[i]) - '@';
  447.                 else
  448.                     SharedBuffer[Count++] = String[i];
  449.  
  450.                 GotEscape = FALSE;
  451.             }
  452.  
  453.                 /* The next character represents a command. */
  454.  
  455.             if(GotControl)
  456.             {
  457.                 switch(ToUpper(String[i]))
  458.                 {
  459.                         /* Fall back to default send mode. */
  460.  
  461.                     case '0':
  462.  
  463.                         if(Count)
  464.                         {
  465.                             (*SendLineLocal)(SharedBuffer,Count);
  466.  
  467.                             Count = 0;
  468.                         }
  469.  
  470.                         SendLineLocal = SendLine;
  471.                         break;
  472.  
  473.                         /* Select `direct' send mode. */
  474.  
  475.                     case '1':
  476.  
  477.                         if(Count)
  478.                         {
  479.                             (*SendLineLocal)(SharedBuffer,Count);
  480.  
  481.                             Count = 0;
  482.                         }
  483.  
  484.                         SendLineLocal = SendLineSimple;
  485.                         break;
  486.  
  487.                         /* Select `echo' send mode. */
  488.  
  489.                     case '2':
  490.  
  491.                         if(Count)
  492.                         {
  493.                             (*SendLineLocal)(SharedBuffer,Count);
  494.  
  495.                             Count = 0;
  496.                         }
  497.  
  498.                         if(Config -> ClipConfig -> SendTimeout)
  499.                             SendLineLocal = SendLineEcho;
  500.                         else
  501.                             SendLineLocal = SendLineSimple;
  502.  
  503.                         break;
  504.  
  505.                         /* Select `any echo' send mode. */
  506.  
  507.                     case '3':
  508.  
  509.                         if(Count)
  510.                         {
  511.                             (*SendLineLocal)(SharedBuffer,Count);
  512.  
  513.                             Count = 0;
  514.                         }
  515.  
  516.                         if(Config -> ClipConfig -> SendTimeout)
  517.                             SendLineLocal = SendLineAnyEcho;
  518.                         else
  519.                             SendLineLocal = SendLineSimple;
  520.  
  521.                         break;
  522.  
  523.                         /* Select `prompt' send mode. */
  524.  
  525.                     case '4':
  526.  
  527.                         if(Count)
  528.                         {
  529.                             (*SendLineLocal)(SharedBuffer,Count);
  530.  
  531.                             Count = 0;
  532.                         }
  533.  
  534.                         if(Config -> ClipConfig -> SendTimeout)
  535.                             SendLineLocal = SendLinePrompt;
  536.                         else
  537.                             SendLineLocal = SendLineSimple;
  538.  
  539.                         break;
  540.  
  541.                         /* Select `delay' send mode. */
  542.  
  543.                     case '5':
  544.  
  545.                         if(Count)
  546.                         {
  547.                             (*SendLineLocal)(SharedBuffer,Count);
  548.  
  549.                             Count = 0;
  550.                         }
  551.  
  552.                         if(Config -> ClipConfig -> LineDelay || Config -> ClipConfig -> CharDelay)
  553.                             SendLineLocal = SendLineDelay;
  554.                         else
  555.                             SendLineLocal = SendLineSimple;
  556.  
  557.                         break;
  558.  
  559.                         /* Select `keyboard' send mode. */
  560.  
  561.                     case '6':
  562.  
  563.                         if(Count)
  564.                         {
  565.                             (*SendLineLocal)(SharedBuffer,Count);
  566.  
  567.                             Count = 0;
  568.                         }
  569.  
  570.                         SendLineLocal = SendLineKeyDelay;
  571.                         break;
  572.  
  573.                         /* Translate code. */
  574.  
  575.                     case '*':
  576.  
  577.                         i++;
  578.  
  579.                         while(i < Len && String[i] == ' ')
  580.                             i++;
  581.  
  582.                         if(i < Len)
  583.                         {
  584.                             UBYTE DummyBuffer[5];
  585.                             LONG j = 0,Char;
  586.  
  587.                             if(String[i] >= '0' && String[i] <= '9')
  588.                             {
  589.                                 while(j < 3 && i < Len)
  590.                                 {
  591.                                     Char = String[i++];
  592.  
  593.                                     if(Char >= '0' && Char <= '9')
  594.                                         DummyBuffer[j++] = Char;
  595.                                     else
  596.                                     {
  597.                                         i--;
  598.  
  599.                                         break;
  600.                                     }
  601.                                 }
  602.                             }
  603.                             else
  604.                             {
  605.                                 while(j < 4 && i < Len)
  606.                                 {
  607.                                     Char = ToLower(String[i++]);
  608.  
  609.                                     if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
  610.                                         DummyBuffer[j++] = Char;
  611.                                     else
  612.                                     {
  613.                                         i--;
  614.  
  615.                                         break;
  616.                                     }
  617.                                 }
  618.                             }
  619.  
  620.                             DummyBuffer[j] = 0;
  621.  
  622.                             SharedBuffer[Count++] = NameToCode(DummyBuffer);
  623.                         }
  624.  
  625.                         i--;
  626.  
  627.                         break;
  628.  
  629.                         /* Execute an AmigaDOS command. */
  630.  
  631.                     case 'D':
  632.  
  633.                         if(!InRexx)
  634.                         {
  635.                             if(!WeAreBlocking)
  636.                             {
  637.                                 BlockWindows();
  638.  
  639.                                 SendAmigaDOSCommand(&String[i + 1]);
  640.  
  641.                                 ReleaseWindows();
  642.                             }
  643.                             else
  644.                                 SendAmigaDOSCommand(&String[i + 1]);
  645.                         }
  646.  
  647.                         return;
  648.  
  649.                         /* Execute an ARexx command. */
  650.  
  651.                     case 'A':
  652.  
  653.                         if(!InRexx)
  654.                         {
  655.                             if(!WeAreBlocking)
  656.                             {
  657.                                 BlockWindows();
  658.  
  659.                                 SendARexxCommand(&String[i + 1],TRUE);
  660.  
  661.                                 ReleaseWindows();
  662.                             }
  663.                             else
  664.                                 SendARexxCommand(&String[i + 1],TRUE);
  665.                         }
  666.  
  667.                         return;
  668.  
  669.                         /* Add the control character ('\'). */
  670.  
  671.                     case '\\':
  672.  
  673.                         SharedBuffer[Count++] = '\\';
  674.                         break;
  675.  
  676.                         /* This is a backspace. */
  677.  
  678.                     case 'B':
  679.  
  680.                         SharedBuffer[Count++] = '\b';
  681.                         break;
  682.  
  683.                         /* This is a form feed. */
  684.  
  685.                     case 'F':
  686.  
  687.                         SharedBuffer[Count++] = '\f';
  688.                         break;
  689.  
  690.                         /* This is a line feed. */
  691.  
  692.                     case 'N':
  693.  
  694.                         SharedBuffer[Count++] = '\n';
  695.                         break;
  696.  
  697.                         /* Send the current password. */
  698.  
  699.                     case 'P':
  700.  
  701.                         if(Password[0])
  702.                         {
  703.                             if(Count)
  704.                             {
  705.                                 (*SendLineLocal)(SharedBuffer,Count);
  706.  
  707.                                 Count = 0;
  708.                             }
  709.  
  710.                             (*SendLineLocal)(Password,strlen(Password));
  711.                         }
  712.  
  713.                         break;
  714.  
  715.                         /* This is a carriage return. */
  716.  
  717.                     case 'R':
  718.  
  719.                         SharedBuffer[Count++] = '\r';
  720.                         break;
  721.  
  722.                         /* This is a tab. */
  723.  
  724.                     case 'T':
  725.  
  726.                         SharedBuffer[Count++] = '\t';
  727.                         break;
  728.  
  729.                         /* Send the current user name. */
  730.  
  731.                     case 'U':
  732.  
  733.                         if(UserName[0])
  734.                         {
  735.                             if(Count)
  736.                             {
  737.                                 (*SendLineLocal)(SharedBuffer,Count);
  738.  
  739.                                 Count = 0;
  740.                             }
  741.  
  742.                             (*SendLineLocal)(UserName,strlen(UserName));
  743.                         }
  744.  
  745.                         break;
  746.  
  747.                         /* Send a break across the serial line. */
  748.  
  749.                     case 'X':
  750.  
  751.                         if(Count)
  752.                         {
  753.                             (*SendLineLocal)(SharedBuffer,Count);
  754.  
  755.                             Count = 0;
  756.                         }
  757.  
  758.                         SendBreak();
  759.  
  760.                         break;
  761.  
  762.                         /* Feed the contents of the
  763.                          * clipboard into the input
  764.                          * stream.
  765.                          */
  766.  
  767.                     case 'I':
  768.  
  769.                         if(Count)
  770.                             (*SendLineLocal)(SharedBuffer,Count);
  771.  
  772.                         Count = LoadClip(SharedBuffer,256);
  773.  
  774.                         break;
  775.  
  776.                         /* Send a string to the clipboard. */
  777.  
  778.                     case 'G':
  779.  
  780.                         if(String[i + 1])
  781.                             SaveClip(&String[i + 1],strlen(&String[i + 1]));
  782.  
  783.                         return;
  784.  
  785.                         /* Send a string to the clipboard. */
  786.  
  787.                     case 'H':
  788.  
  789.                         if(String[i + 1])
  790.                             AddClip(&String[i + 1],strlen(&String[i + 1]));
  791.  
  792.                         return;
  793.  
  794.                         /* Produce the escape character. */
  795.  
  796.                     case 'E':
  797.  
  798.                         SharedBuffer[Count++] = ESC;
  799.                         break;
  800.  
  801.                         /* Call a menu item. */
  802.  
  803.                     case 'C':
  804.  
  805.                         i++;
  806.  
  807.                             /* Scan for a menu number or
  808.                              * a single quote...
  809.                              */
  810.  
  811.                         while(i < Len)
  812.                         {
  813.                             if(String[i] >= '0' && String[i] <= '9')
  814.                                 break;
  815.  
  816.                             if(String[i] == '\'')
  817.                                 break;
  818.  
  819.                             if(String[i] != ' ')
  820.                                 break;
  821.  
  822.                             i++;
  823.                         }
  824.  
  825.                         if(i < Len)
  826.                         {
  827.                             UBYTE DummyBuffer[256];
  828.  
  829.                                 /* Did we get a quote? */
  830.  
  831.                             if(String[i] == '\'')
  832.                             {
  833.                                 LONG Start = ++i;
  834.  
  835.                                 if(String[Start])
  836.                                 {
  837.                                     LONG Length;
  838.  
  839.                                     while(i < Len)
  840.                                     {
  841.                                         if(String[i] != '\'')
  842.                                             i++;
  843.                                         else
  844.                                             break;
  845.                                     }
  846.  
  847.                                     if(String[i] == '\'')
  848.                                         Length = i - Start;
  849.                                     else
  850.                                         Length = i - Start + 1;
  851.  
  852.                                     CopyMem(&String[Start],DummyBuffer,Length);
  853.  
  854.                                     DummyBuffer[Length] = 0;
  855.  
  856.                                     CallMenu(DummyBuffer,0);
  857.                                 }
  858.                             }
  859.                             else
  860.                             {
  861.                                 if(String[i] >= '0' && String[i] <= '9')
  862.                                 {
  863.                                     LONG Start = i,Length;
  864.  
  865.                                     while(i < Len)
  866.                                     {
  867.                                         if(String[i] >= '0' && String[i] <= '9')
  868.                                             i++;
  869.                                         else
  870.                                             break;
  871.                                     }
  872.  
  873.                                     if(i == Start)
  874.                                         Length = 1;
  875.                                     else
  876.                                         Length = i - Start;
  877.  
  878.                                     CopyMem(&String[Start],DummyBuffer,Length);
  879.  
  880.                                     DummyBuffer[Length] = 0;
  881.  
  882.                                     CallMenu(NULL,Atol(DummyBuffer));
  883.                                 }
  884.                             }
  885.                         }
  886.  
  887.                         break;
  888.  
  889.                         /* Insert the current dialing mode suffix. */
  890.  
  891.                     case 'W':
  892.                     {
  893.                         UBYTE c;
  894.  
  895.                         switch(Config -> ModemConfig -> DialMode)
  896.                         {
  897.                             case DIALMODE_TONE:
  898.  
  899.                                 c = 'T';
  900.                                 break;
  901.  
  902.                             case DIALMODE_MODEM:
  903.  
  904.                                 c = 'M';
  905.                                 break;
  906.  
  907.                             case DIALMODE_ISDN:
  908.  
  909.                                 c = 'I';
  910.                                 break;
  911.  
  912.                             default:
  913.  
  914.                                 c = 'P';    // Pulse
  915.                                 break;
  916.                         }
  917.  
  918.                         SharedBuffer[Count++] = c;
  919.  
  920.                         break;
  921.                     }
  922.  
  923.                         /* Stuff the character into the buffer. */
  924.  
  925.                     default:
  926.  
  927.                         SharedBuffer[Count++] = String[i];
  928.                         break;
  929.                 }
  930.  
  931.                 GotControl = FALSE;
  932.             }
  933.         }
  934.  
  935.             /* If the buffer is full, release it. */
  936.  
  937.         if(Count == 256)
  938.         {
  939.             (*SendLineLocal)(SharedBuffer,Count);
  940.  
  941.             Count = 0;
  942.         }
  943.     }
  944.  
  945.     if(Count)
  946.         (*SendLineLocal)(SharedBuffer,Count);
  947. }
  948.  
  949.     /* SerWriteVerbatim(APTR Buffer,LONG Size,BOOL Echo):
  950.      *
  951.      *    The `no fancy features' version of SerWrite().
  952.      */
  953.  
  954. VOID
  955. SerWriteVerbatim(APTR Buffer,LONG Size,BOOL Echo)
  956. {
  957.     if(XProtocolBase && (TransferBits & XPRS_USERMON))
  958.         Size = XProtocolUserMon(XprIO,Buffer,Size,Size);
  959.  
  960.     if(Size > 0)
  961.     {
  962.         if(Echo)
  963.         {
  964.             if(Marking)
  965.                 DropMarker();
  966.  
  967.             StartSerialWrite(Buffer,Size);
  968.  
  969.             ConProcess(Buffer,Size);
  970.  
  971.             WaitSerialWrite();
  972.         }
  973.         else
  974.             DoSerialWrite(Buffer,Size);
  975.  
  976.         BytesOut += Size;
  977.     }
  978. }
  979.  
  980.     /* SerWrite(APTR Buffer,LONG Size):
  981.      *
  982.      *    Send a number of bytes across the serial line.
  983.      */
  984.  
  985. VOID
  986. SerWrite(APTR Buffer,LONG Size)
  987. {
  988.     if(Size < 0)
  989.         Size = strlen(Buffer);
  990.  
  991.     if(Size)
  992.     {
  993.         if(RememberInput)
  994.         {
  995.             RememberInputText(Buffer,Size);
  996.  
  997.             if(((UBYTE *)Buffer)[Size - 1] == '\r' && RecordingLine)
  998.             {
  999.                 RememberSpill();
  1000.  
  1001.                 RecordingLine = FALSE;
  1002.  
  1003.                 RememberOutput = TRUE;
  1004.                 RememberInput = FALSE;
  1005.  
  1006.                 CheckItem(MEN_RECORD_LINE,FALSE);
  1007.             }
  1008.         }
  1009.         else
  1010.         {
  1011.             if(RememberOutput)
  1012.             {
  1013.                 RememberInputText(Buffer,Size);
  1014.  
  1015.                 RememberSpill();
  1016.             }
  1017.         }
  1018.  
  1019.         if(WriteRequest)
  1020.         {
  1021.             STATIC UBYTE TranslateData[512];
  1022.  
  1023.                 /* xpr wants to see the data before it is
  1024.                  * transferred.
  1025.                  */
  1026.  
  1027.             if(XProtocolBase && (TransferBits & XPRS_USERMON))
  1028.             {
  1029.                 if(Size = XProtocolUserMon(XprIO,Buffer,Size,Size))
  1030.                 {
  1031.                     if(SendTable)
  1032.                     {
  1033.                         struct TranslationHandle Handle;
  1034.  
  1035.                             /* Set up for buffer translation. */
  1036.  
  1037.                         TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
  1038.  
  1039.                             /* Full or half duplex? */
  1040.  
  1041.                         if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  1042.                         {
  1043.                             if(SerWriteBypass)
  1044.                             {
  1045.                                     /* Process the data... */
  1046.  
  1047.                                 while(Size = TranslateBuffer(&Handle))
  1048.                                 {
  1049.                                     if((*SerWriteBypass)(TranslateData,Size))
  1050.                                     {
  1051.                                             /* ...and send it. */
  1052.  
  1053.                                         DoSerialWrite(TranslateData,Size);
  1054.                                     }
  1055.  
  1056.                                     BytesOut += Size;
  1057.                                 }
  1058.                             }
  1059.                             else
  1060.                             {
  1061.                                     /* Process the data... */
  1062.  
  1063.                                 while(Size = TranslateBuffer(&Handle))
  1064.                                 {
  1065.                                         /* ...and send it. */
  1066.  
  1067.                                     DoSerialWrite(TranslateData,Size);
  1068.  
  1069.                                     BytesOut += Size;
  1070.                                 }
  1071.                             }
  1072.                         }
  1073.                         else
  1074.                         {
  1075.                             if(Marking)
  1076.                                 DropMarker();
  1077.  
  1078.                             if(SerWriteBypass)
  1079.                             {
  1080.                                 while(Size = TranslateBuffer(&Handle))
  1081.                                 {
  1082.                                     if((*SerWriteBypass)(TranslateData,Size))
  1083.                                     {
  1084.                                             /* Process the data while it is transferred. */
  1085.  
  1086.                                         StartSerialWrite(TranslateData,Size);
  1087.  
  1088.                                         ConProcess(Buffer,Size);
  1089.  
  1090.                                         WaitSerialWrite();
  1091.                                     }
  1092.  
  1093.                                     BytesOut += Size;
  1094.                                 }
  1095.                             }
  1096.                             else
  1097.                             {
  1098.                                 while(Size = TranslateBuffer(&Handle))
  1099.                                 {
  1100.                                         /* Process the data while it is transferred. */
  1101.  
  1102.                                     StartSerialWrite(TranslateData,Size);
  1103.  
  1104.                                     ConProcess(TranslateData,Size);
  1105.  
  1106.                                     WaitSerialWrite();
  1107.  
  1108.                                     BytesOut += Size;
  1109.                                 }
  1110.                             }
  1111.                         }
  1112.                     }
  1113.                     else
  1114.                     {
  1115.                         if(SerWriteBypass)
  1116.                         {
  1117.                             if((*SerWriteBypass)(Buffer,Size))
  1118.                             {
  1119.                                     /* If full duplex is enabled, send the entire
  1120.                                      * buffer without processing.
  1121.                                      */
  1122.  
  1123.                                 if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  1124.                                     DoSerialWrite(Buffer,Size);
  1125.                                 else
  1126.                                 {
  1127.                                         /* Process the data while it is transferred. */
  1128.  
  1129.                                     StartSerialWrite(Buffer,Size);
  1130.  
  1131.                                     if(Marking)
  1132.                                         DropMarker();
  1133.  
  1134.                                     ConProcess(Buffer,Size);
  1135.  
  1136.                                     WaitSerialWrite();
  1137.                                 }
  1138.                             }
  1139.                             else
  1140.                             {
  1141.                                 if(Config -> SerialConfig -> Duplex != DUPLEX_FULL)
  1142.                                 {
  1143.                                     if(Marking)
  1144.                                         DropMarker();
  1145.  
  1146.                                     ConProcess(Buffer,Size);
  1147.                                 }
  1148.                             }
  1149.                         }
  1150.                         else
  1151.                         {
  1152.                                 /* If full duplex is enabled, send the entire
  1153.                                  * buffer without processing.
  1154.                                  */
  1155.  
  1156.                             if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  1157.                                 DoSerialWrite(Buffer,Size);
  1158.                             else
  1159.                             {
  1160.                                     /* Process the data while it is transferred. */
  1161.  
  1162.                                 StartSerialWrite(Buffer,Size);
  1163.  
  1164.                                 if(Marking)
  1165.                                     DropMarker();
  1166.  
  1167.                                 ConProcess(Buffer,Size);
  1168.  
  1169.                                 WaitSerialWrite();
  1170.                             }
  1171.                         }
  1172.  
  1173.                         BytesOut += Size;
  1174.                     }
  1175.                 }
  1176.             }
  1177.             else
  1178.             {
  1179.                 if(SendTable)
  1180.                 {
  1181.                     struct TranslationHandle Handle;
  1182.  
  1183.                         /* Set up for buffer translation. */
  1184.  
  1185.                     TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
  1186.  
  1187.                         /* Full or half duplex? */
  1188.  
  1189.                     if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  1190.                     {
  1191.                         if(SerWriteBypass)
  1192.                         {
  1193.                                 /* Process the data... */
  1194.  
  1195.                             while(Size = TranslateBuffer(&Handle))
  1196.                             {
  1197.                                 if((*SerWriteBypass)(TranslateData,Size))
  1198.                                 {
  1199.                                         /* ...and send it. */
  1200.  
  1201.                                     DoSerialWrite(TranslateData,Size);
  1202.                                 }
  1203.  
  1204.                                 BytesOut += Size;
  1205.                             }
  1206.                         }
  1207.                         else
  1208.                         {
  1209.                                 /* Process the data... */
  1210.  
  1211.                             while(Size = TranslateBuffer(&Handle))
  1212.                             {
  1213.                                     /* ...and send it. */
  1214.  
  1215.                                 DoSerialWrite(TranslateData,Size);
  1216.  
  1217.                                 BytesOut += Size;
  1218.                             }
  1219.                         }
  1220.                     }
  1221.                     else
  1222.                     {
  1223.                         if(Marking)
  1224.                             DropMarker();
  1225.  
  1226.                         if(SerWriteBypass)
  1227.                         {
  1228.                             while(Size = TranslateBuffer(&Handle))
  1229.                             {
  1230.                                 if((*SerWriteBypass)(TranslateData,Size))
  1231.                                 {
  1232.                                         /* Process the data while it is transferred. */
  1233.  
  1234.                                     StartSerialWrite(TranslateData,Size);
  1235.  
  1236.                                     ConProcess(TranslateData,Size);
  1237.  
  1238.                                     WaitSerialWrite();
  1239.                                 }
  1240.  
  1241.                                 BytesOut += Size;
  1242.                             }
  1243.                         }
  1244.                         else
  1245.                         {
  1246.                             while(Size = TranslateBuffer(&Handle))
  1247.                             {
  1248.                                     /* Process the data while it is transferred. */
  1249.  
  1250.                                 StartSerialWrite(TranslateData,Size);
  1251.  
  1252.                                 ConProcess(TranslateData,Size);
  1253.  
  1254.                                 WaitSerialWrite();
  1255.  
  1256.                                 BytesOut += Size;
  1257.                             }
  1258.                         }
  1259.                     }
  1260.                 }
  1261.                 else
  1262.                 {
  1263.                     if(SerWriteBypass)
  1264.                     {
  1265.                         if((*SerWriteBypass)(Buffer,Size))
  1266.                         {
  1267.                                 /* If full duplex is enabled, send the entire
  1268.                                  * buffer without processing.
  1269.                                  */
  1270.  
  1271.                             if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  1272.                                 DoSerialWrite(Buffer,Size);
  1273.                             else
  1274.                             {
  1275.                                     /* Process the data while it is transferred. */
  1276.  
  1277.                                 StartSerialWrite(Buffer,Size);
  1278.  
  1279.                                 if(Marking)
  1280.                                     DropMarker();
  1281.  
  1282.                                 ConProcess(Buffer,Size);
  1283.  
  1284.                                 WaitSerialWrite();
  1285.                             }
  1286.                         }
  1287.                     }
  1288.                     else
  1289.                     {
  1290.                             /* If full duplex is enabled, send the entire
  1291.                              * buffer without processing.
  1292.                              */
  1293.  
  1294.                         if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  1295.                             DoSerialWrite(Buffer,Size);
  1296.                         else
  1297.                         {
  1298.                                 /* Process the data while it is transferred. */
  1299.  
  1300.                             StartSerialWrite(Buffer,Size);
  1301.  
  1302.                             if(Marking)
  1303.                                 DropMarker();
  1304.  
  1305.                             ConProcess(Buffer,Size);
  1306.  
  1307.                             WaitSerialWrite();
  1308.                         }
  1309.                     }
  1310.  
  1311.                     BytesOut += Size;
  1312.                 }
  1313.             }
  1314.         }
  1315.     }
  1316. }
  1317.  
  1318.     /* RestartSerial():
  1319.      *
  1320.      *    Restart read/write activity on the serial line.
  1321.      */
  1322.  
  1323. VOID
  1324. RestartSerial()
  1325. {
  1326.     StartSerialRead(ReadBuffer,1);
  1327. }
  1328.  
  1329.     /* ClearSerial():
  1330.      *
  1331.      *    Terminate all read/write activity on the serial line.
  1332.      */
  1333.  
  1334. VOID
  1335. ClearSerial()
  1336. {
  1337.     StopSerialRead();
  1338.  
  1339.     DoSerialCmd(CMD_CLEAR);
  1340. }
  1341.  
  1342.     /* DeleteSerial():
  1343.      *
  1344.      *    Close the serial device and release all associated
  1345.      *    resources.
  1346.      */
  1347.  
  1348. VOID
  1349. DeleteSerial()
  1350. {
  1351.     BOOL Closed = FALSE;
  1352.  
  1353.     if(ReadRequest)
  1354.     {
  1355.         if(ReadRequest -> IOSer . io_Device)
  1356.         {
  1357.             struct Device    *Device;
  1358.             UBYTE             Name[MAX_FILENAME_LENGTH];
  1359.  
  1360.             StopSerialRead();
  1361.  
  1362.             if(!Config -> SerialConfig -> Shared)
  1363.             {
  1364.                 ReadRequest -> IOSer . io_Command = CMD_RESET;
  1365.  
  1366.                 DoIO(ReadRequest);
  1367.             }
  1368.  
  1369.             strcpy(Name,ReadRequest -> IOSer . io_Device -> dd_Library . lib_Node . ln_Name);
  1370.  
  1371.             CloseDevice(ReadRequest);
  1372.  
  1373.             Forbid();
  1374.  
  1375.             if(Device = (struct Device *)FindName(&SysBase -> DeviceList,Name))
  1376.                 RemDevice(Device);
  1377.  
  1378.             Permit();
  1379.  
  1380.             Closed = TRUE;
  1381.         }
  1382.  
  1383.         DeleteIORequest(ReadRequest);
  1384.  
  1385.         ReadRequest = NULL;
  1386.     }
  1387.  
  1388.     if(WriteRequest)
  1389.     {
  1390.         if(WriteRequest -> IOSer . io_Device && !Closed)
  1391.         {
  1392.             struct Device    *Device;
  1393.             UBYTE             Name[MAX_FILENAME_LENGTH];
  1394.  
  1395.             StopSerialWrite();
  1396.  
  1397.             strcpy(Name,WriteRequest -> IOSer . io_Device -> dd_Library . lib_Node . ln_Name);
  1398.  
  1399.             CloseDevice(WriteRequest);
  1400.  
  1401.             Forbid();
  1402.  
  1403.             if(Device = (struct Device *)FindName(&SysBase -> DeviceList,Name))
  1404.                 RemDevice(Device);
  1405.  
  1406.             Permit();
  1407.         }
  1408.  
  1409.         if(WriteRequest -> IOSer . io_Message . mn_ReplyPort)
  1410.             DeleteMsgPort(WriteRequest -> IOSer . io_Message . mn_ReplyPort);
  1411.  
  1412.         DeleteIORequest(WriteRequest);
  1413.  
  1414.         WriteRequest = NULL;
  1415.     }
  1416.  
  1417.     if(ReadPort)
  1418.     {
  1419.         DeleteMsgPort(ReadPort);
  1420.  
  1421.         ReadPort = NULL;
  1422.     }
  1423.  
  1424.     FreeVecPooled(ReadBuffer);
  1425.     ReadBuffer = NULL;
  1426.  
  1427.     FreeVecPooled(HostReadBuffer);
  1428.     HostReadBuffer = NULL;
  1429.  
  1430.     FreeVecPooled(StripBuffer);
  1431.     StripBuffer = NULL;
  1432.  
  1433.     if(OwnDevUnitBase && SerialDevice[0] && UnitNumber != -1 && SerialLocked)
  1434.     {
  1435.         FreeDevUnit(SerialDevice,UnitNumber);
  1436.  
  1437.         SerialDevice[0] = 0;
  1438.  
  1439.         UnitNumber = -1;
  1440.     }
  1441.  
  1442.     if(OwnDevBit != -1)
  1443.     {
  1444.         FreeSignal(OwnDevBit);
  1445.  
  1446.         OwnDevBit = -1;
  1447.     }
  1448.  
  1449.     SerialLocked = FALSE;
  1450.  
  1451.     ResetSerialRead();
  1452.     ResetSerialWrite();
  1453. }
  1454.  
  1455.     /* GetSerialError(LONG Error,BOOL *Reset):
  1456.      *
  1457.      *    Return an error message for each possible serial device error.
  1458.      */
  1459.  
  1460. STRPTR
  1461. GetSerialError(LONG Error,BOOL *Reset)
  1462. {
  1463.     if(Reset)
  1464.         *Reset = FALSE;
  1465.  
  1466.     switch(Error)
  1467.     {
  1468.         case IOERR_BADLENGTH:
  1469.         case IOERR_BADADDRESS:
  1470.         case IOERR_SELFTEST:
  1471.         case IOERR_OPENFAIL:
  1472.  
  1473.             return(LocaleString(MSG_SERIAL_OPENFAILURE_TXT));
  1474.  
  1475.         case SerErr_DevBusy:
  1476.  
  1477.             return(LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT));
  1478.  
  1479.         case SerErr_BaudMismatch:
  1480.  
  1481.             if(Reset)
  1482.                 *Reset = TRUE;
  1483.  
  1484.             return(LocaleString(MSG_SERIAL_ERROR_BAUDMISMATCH_TXT));
  1485.  
  1486.         case SerErr_BufErr:
  1487.  
  1488.             if(Reset)
  1489.                 *Reset = TRUE;
  1490.  
  1491.             return(LocaleString(MSG_SERIAL_ERROR_BUFERR_TXT));
  1492.  
  1493.         case SerErr_InvParam:
  1494.  
  1495.             if(Reset)
  1496.                 *Reset = TRUE;
  1497.  
  1498.             return(LocaleString(MSG_SERIAL_ERROR_INVPARAM_TXT));
  1499.  
  1500.         case SerErr_LineErr:
  1501.  
  1502.             return(LocaleString(MSG_SERIAL_ERROR_LINEERR_TXT));
  1503.  
  1504.         case SerErr_ParityErr:
  1505.  
  1506.             if(Reset)
  1507.                 *Reset = TRUE;
  1508.  
  1509.             return(LocaleString(MSG_SERIAL_ERROR_PARITYERR_TXT));
  1510.  
  1511.         case SerErr_TimerErr:
  1512.  
  1513.             return(LocaleString(MSG_SERIAL_ERROR_TIMERERR_TXT));
  1514.  
  1515.         case SerErr_BufOverflow:
  1516.  
  1517.             if(Reset)
  1518.                 *Reset = TRUE;
  1519.  
  1520.             return(LocaleString(MSG_SERIAL_ERROR_BUFOVERFLOW_TXT));
  1521.  
  1522.         case SerErr_NoDSR:
  1523.  
  1524.             return(LocaleString(MSG_SERIAL_ERROR_NODSR_TXT));
  1525.  
  1526.     /*    case SerErr_UnitBusy:    */
  1527.         case IOERR_UNITBUSY:
  1528.         case 16:
  1529.  
  1530.             return(LocaleString(MSG_SERIAL_ERROR_UNIT_BUSY_TXT));
  1531.  
  1532.         default:
  1533.  
  1534.             return(NULL);
  1535.     }
  1536. }
  1537.  
  1538.     /* CreateSerial():
  1539.      *
  1540.      *    Create handles for the serial device and open it.
  1541.      */
  1542.  
  1543. STRPTR
  1544. CreateSerial()
  1545. {
  1546.     struct MsgPort *WritePort;
  1547.  
  1548.         /* If OwnDevUnit.library is available, try to lock
  1549.          * the serial driver.
  1550.          */
  1551.  
  1552.     if(OwnDevUnitBase && Config -> SerialConfig -> UseOwnDevUnit && !(Config -> SerialConfig -> Shared && Config -> SerialConfig -> NoODUIfShared))
  1553.     {
  1554.         STRPTR Error;
  1555.  
  1556.             /* Allocate a signal for OwnDevUnit, in case we might need it. */
  1557.  
  1558.         if(OwnDevBit == -1)
  1559.         {
  1560.             OwnDevBit = AllocSignal(-1);
  1561.  
  1562.                 /* Attempt to lock the device unit... */
  1563.  
  1564.             Error = AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,OwnDevBit == -1 ? NULL : OwnDevBit);
  1565.         }
  1566.         else
  1567.             Error = NULL;
  1568.  
  1569.         if(Error)
  1570.         {
  1571.                 /* Check for error type if any. */
  1572.  
  1573.             if(!Strnicmp(Error,ODUERR_LEADCHAR,1))
  1574.                 SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_ERROR_ACCESSING_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,&Error[1]);
  1575.             else
  1576.                 SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_DEVICE_IN_USE_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,Error);
  1577.  
  1578.             SerialDevice[0] = 0;
  1579.  
  1580.             UnitNumber = -1;
  1581.  
  1582.             SerialLocked = FALSE;
  1583.  
  1584.             return(SharedBuffer);
  1585.         }
  1586.         else
  1587.         {
  1588.             strcpy(SerialDevice,Config -> SerialConfig -> SerialDevice);
  1589.  
  1590.             UnitNumber = Config -> SerialConfig -> UnitNumber;
  1591.  
  1592.             SerialLocked = TRUE;
  1593.         }
  1594.     }
  1595.     else
  1596.         SerialLocked = FALSE;
  1597.  
  1598.     Update_CR_LF_Translation();
  1599.  
  1600.     if(ReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1601.     {
  1602.         if(StripBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1603.         {
  1604.             if(XProtocolBase && (TransferBits & XPRS_HOSTNOWAIT))
  1605.                 HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  1606.             else
  1607.                 HostReadBuffer = NULL;
  1608.  
  1609.             if(ReadPort = (struct MsgPort *)CreateMsgPort())
  1610.             {
  1611.                 if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
  1612.                 {
  1613.                     if(WritePort = (struct MsgPort *)CreateMsgPort())
  1614.                     {
  1615.                         if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
  1616.                         {
  1617.                             BYTE HandshakingProtocol = Config -> SerialConfig -> HandshakingProtocol;
  1618.                             LONG Error;
  1619.  
  1620.                                 /* In order to avoid trouble, the device driver is to be opened in
  1621.                                  * plain mode, i.e. no RTS/CTS handshaking will be enabled.
  1622.                                  */
  1623.  
  1624.                             if(Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_RTSCTS_DSR)
  1625.                                 HandshakingProtocol = HANDSHAKING_RTSCTS;
  1626.  
  1627.                             UseRTS_CTS = TRUE;
  1628.  
  1629. Reset:                        SetSerialReadAttributes(
  1630.                                 SERA_Baud,            Config -> SerialConfig -> BaudRate,
  1631.                                 SERA_BreakTime,        Config -> SerialConfig -> BreakLength,
  1632.                                 SERA_BitsPerChar,    Config -> SerialConfig -> BitsPerChar,
  1633.                                 SERA_StopBits,        Config -> SerialConfig -> StopBits,
  1634.                                 SERA_BufferSize,    Config -> SerialConfig -> SerialBufferSize,
  1635.                                 SERA_Parity,        Config -> SerialConfig -> Parity,
  1636.                                 SERA_Handshaking,    HandshakingProtocol,
  1637.                                 SERA_HighSpeed,        Config -> SerialConfig -> HighSpeed,
  1638.                                 SERA_Shared,        Config -> SerialConfig -> Shared,
  1639.                             TAG_DONE);
  1640.  
  1641.                             if(!(Error = OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0)))
  1642.                             {
  1643.                                 CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  1644.  
  1645.                                 WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  1646.  
  1647.                                 if(Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_RTSCTS_DSR && HandshakingProtocol == HANDSHAKING_RTSCTS)
  1648.                                 {
  1649.                                         /* Now check if the DSR signal is enabled. */
  1650.  
  1651.                                     if(GetSerialStatus() & CIAF_COMDSR)
  1652.                                     {
  1653.                                             /* If this is the first time the driver gets initialized,
  1654.                                              * skip the notification message and just drop the RTS/CTS
  1655.                                              * handshaking bit.
  1656.                                              */
  1657.  
  1658.                                         if(FirstInvocation)
  1659.                                             UseRTS_CTS = FALSE;
  1660.                                         else
  1661.                                         {
  1662.                                             do
  1663.                                             {
  1664.                                                 if(!ShowRequest(Window,LocaleString(MSG_SERIAL_NO_DSR_SIGNAL_TXT),LocaleString(MSG_SERIAL_RETRY_CANCEL_TXT)))
  1665.                                                 {
  1666.                                                     UseRTS_CTS = FALSE;
  1667.                                                     break;
  1668.                                                 }
  1669.                                             }
  1670.                                             while(GetSerialStatus() & CIAF_COMDSR);
  1671.                                         }
  1672.                                     }
  1673.  
  1674.                                     if(!UseRTS_CTS)
  1675.                                     {
  1676.                                         CloseDevice(ReadRequest);
  1677.  
  1678.                                         ReadRequest -> IOSer . io_Device = NULL;
  1679.  
  1680.                                         HandshakingProtocol = HANDSHAKING_NONE;
  1681.  
  1682.                                         goto Reset;
  1683.                                     }
  1684.                                 }
  1685.  
  1686.                                 ResetSerialRead();
  1687.                                 ResetSerialWrite();
  1688.  
  1689.                                 SetFlags();
  1690.  
  1691.                                 RestartSerial();
  1692.  
  1693.                                 return(NULL);
  1694.                             }
  1695.                             else
  1696.                             {
  1697.                                 STRPTR String;
  1698.  
  1699.                                 ReadRequest -> IOSer . io_Device = NULL;
  1700.  
  1701.                                 DeleteSerial();
  1702.  
  1703.                                 SerialMessage = NULL;
  1704.  
  1705.                                 if(!(String = GetSerialError(Error,NULL)))
  1706.                                     String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
  1707.  
  1708.                                 SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
  1709.  
  1710.                                 return(SharedBuffer);
  1711.                             }
  1712.                         }
  1713.                     }
  1714.                     else
  1715.                     {
  1716.                         SerialMessage = NULL;
  1717.  
  1718.                         DeleteSerial();
  1719.  
  1720.                         return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_WRITE_PORT_TXT));
  1721.                     }
  1722.                 }
  1723.             }
  1724.             else
  1725.             {
  1726.                 SerialMessage = NULL;
  1727.  
  1728.                 DeleteSerial();
  1729.  
  1730.                 return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_READ_PORT_TXT));
  1731.             }
  1732.         }
  1733.     }
  1734.  
  1735.     SerialMessage = NULL;
  1736.  
  1737.     DeleteSerial();
  1738.  
  1739.     return(LocaleString(MSG_SERIAL_NOT_ENOUGH_MEMORY_TXT));
  1740. }
  1741.  
  1742.     /* ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig):
  1743.      *
  1744.      *    Reconfigure the serial driver according to the new
  1745.      *    serial settings.
  1746.      */
  1747.  
  1748. LONG
  1749. ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig)
  1750. {
  1751.     LONG    Success    = RECONFIGURE_NOCHANGE;
  1752.     BOOL    IsNew;
  1753.  
  1754.         /* Are new settings to be installed or have they already
  1755.          * been copied to the correct locations?
  1756.          */
  1757.  
  1758.     if(SerialConfig)
  1759.     {
  1760.         if(memcmp(Config -> SerialConfig,SerialConfig,sizeof(struct SerialSettings)))
  1761.             IsNew = TRUE;
  1762.         else
  1763.             IsNew = FALSE;
  1764.     }
  1765.     else
  1766.     {
  1767.         if(memcmp(Config -> SerialConfig,PrivateConfig -> SerialConfig,sizeof(struct SerialSettings)))
  1768.             IsNew = TRUE;
  1769.         else
  1770.             IsNew = FALSE;
  1771.     }
  1772.  
  1773.         /* Any changes in the serial configuration area? */
  1774.  
  1775.     if(IsNew)
  1776.     {
  1777.         BOOL SameDevice = TRUE;
  1778.  
  1779.             /* Any new data to swap in? */
  1780.  
  1781.         if(SerialConfig)
  1782.         {
  1783.                 /* Store the previous settings. */
  1784.  
  1785.             SaveConfig(Config,PrivateConfig);
  1786.  
  1787.                 /* Install the new settings. */
  1788.  
  1789.             CopyMem(SerialConfig,Config -> SerialConfig,sizeof(struct SerialSettings));
  1790.         }
  1791.  
  1792.             /* Any device name or unit number change? */
  1793.  
  1794.         if(strcmp(PrivateConfig -> SerialConfig -> SerialDevice,Config -> SerialConfig -> SerialDevice) || PrivateConfig -> SerialConfig -> UnitNumber != Config -> SerialConfig -> UnitNumber || PrivateConfig -> SerialConfig -> UseOwnDevUnit != Config -> SerialConfig -> UseOwnDevUnit)
  1795.             SameDevice = FALSE;
  1796.         else
  1797.         {
  1798.                 /* Handshaking mode changed to RTS/CTS protocol? */
  1799.  
  1800.             if((PrivateConfig -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE) || (PrivateConfig -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE))
  1801.                 SameDevice = FALSE;
  1802.             else
  1803.             {
  1804.                     // Did the ODU options change?
  1805.  
  1806.                 if(PrivateConfig -> SerialConfig -> NoODUIfShared != Config -> SerialConfig -> NoODUIfShared && Config -> SerialConfig -> Shared)
  1807.                     SameDevice = FALSE;
  1808.             }
  1809.         }
  1810.  
  1811.             /* Stop any IO activity. */
  1812.  
  1813.         if(ReadRequest)
  1814.             ClearSerial();
  1815.         else
  1816.             SameDevice = FALSE;
  1817.  
  1818.             /* No dramatic changes? Simply change the parameters. */
  1819.  
  1820.         if(SameDevice)
  1821.         {
  1822.             LONG Error;
  1823.  
  1824.             if(PrivateConfig -> SerialConfig -> SerialBufferSize != Config -> SerialConfig -> SerialBufferSize)
  1825.             {
  1826.                 STRPTR NewReadBuffer;
  1827.  
  1828.                 if(NewReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1829.                 {
  1830.                     STRPTR NewStripBuffer;
  1831.  
  1832.                     if(NewStripBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1833.                     {
  1834.                         FreeVecPooled(ReadBuffer);
  1835.                         FreeVecPooled(StripBuffer);
  1836.  
  1837.                         ReadBuffer    = NewReadBuffer;
  1838.                         StripBuffer    = NewStripBuffer;
  1839.                     }
  1840.                     else
  1841.                     {
  1842.                         FreeVecPooled(NewReadBuffer);
  1843.  
  1844.                         Config -> SerialConfig -> SerialBufferSize = PrivateConfig -> SerialConfig -> SerialBufferSize;
  1845.                     }
  1846.                 }
  1847.                 else
  1848.                     Config -> SerialConfig -> SerialBufferSize = PrivateConfig -> SerialConfig -> SerialBufferSize;
  1849.             }
  1850.  
  1851.             Update_CR_LF_Translation();
  1852.  
  1853.                 /* Use new parameters... */
  1854.  
  1855.             Error = SetFlags();
  1856.  
  1857.                 /* Trouble? */
  1858.  
  1859.             if(Error)
  1860.             {
  1861.                 STRPTR    String;
  1862.                 BOOL    Reset;
  1863.  
  1864.                     /* Query the error message. */
  1865.  
  1866.                 if(!(String = GetSerialError(Error,&Reset)))
  1867.                     String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
  1868.  
  1869.                     /* Build the device name/unit number string. */
  1870.  
  1871.                 SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
  1872.  
  1873.                     /* Display the error requester. */
  1874.  
  1875.                 LT_LockWindow(Window);
  1876.  
  1877.                 ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SharedBuffer);
  1878.  
  1879.                 LT_UnlockWindow(Window);
  1880.  
  1881.                     /* Is a serial driver reset required? */
  1882.  
  1883.                 if(Reset)
  1884.                 {
  1885.                         /* Execute the reset command. */
  1886.  
  1887.                     DoSerialCmd(CMD_RESET);
  1888.  
  1889.                         /* Copy the serial driver settings
  1890.                          * to the global configuration.
  1891.                          */
  1892.  
  1893.                     CopyWriteFlags();
  1894.  
  1895.                         /* Also set the read request driver
  1896.                          * flags.
  1897.                          */
  1898.  
  1899.                     SetFlags();
  1900.                 }
  1901.             }
  1902.  
  1903.                 /* Restart read request. */
  1904.  
  1905.             RestartSerial();
  1906.         }
  1907.         else
  1908.         {
  1909.             STRPTR Error;
  1910.  
  1911.                 /* Shut down the serial driver. */
  1912.  
  1913.             DeleteSerial();
  1914.  
  1915.                 /* Reinitialize the serial driver. */
  1916.  
  1917.             if(!(Error = CreateSerial()))
  1918.             {
  1919.                     /* Free the work buffer. */
  1920.  
  1921.                 if(StripBuffer)
  1922.                     FreeVecPooled(StripBuffer);
  1923.  
  1924.                     /* Try to allocate a new serial data work buffer. */
  1925.  
  1926.                 if(!(StripBuffer = (STRPTR)AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY)))
  1927.                     Error = LocaleString(MSG_GLOBAL_NO_AUX_BUFFERS_TXT);
  1928.             }
  1929.  
  1930.                 /* Trouble? */
  1931.  
  1932.             if(Error)
  1933.             {
  1934.                     /* Display the error requester. */
  1935.  
  1936.                 LT_LockWindow(Window);
  1937.  
  1938.                 ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  1939.  
  1940.                     /* Clean up the mess :-( */
  1941.  
  1942.                 DeleteSerial();
  1943.  
  1944.                 LT_UnlockWindow(Window);
  1945.  
  1946.                 Success = RECONFIGURE_FAILURE;
  1947.             }
  1948.             else
  1949.             {
  1950.                     /* Are we to display an error message? */
  1951.  
  1952.                 if(SerialMessage)
  1953.                 {
  1954.                     ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  1955.  
  1956.                     SerialMessage = NULL;
  1957.                 }
  1958.             }
  1959.         }
  1960.     }
  1961.  
  1962.     return(Success);
  1963. }
  1964.  
  1965.     /* ReopenSerial():
  1966.      *
  1967.      *    Reopen the serial driver.
  1968.      */
  1969.  
  1970. VOID
  1971. ReopenSerial()
  1972. {
  1973.     BOOL    SerialClosed = TRUE;
  1974.     STRPTR    Error;
  1975.  
  1976.     do
  1977.     {
  1978.         if(Error = CreateSerial())
  1979.         {
  1980.             DeleteSerial();
  1981.  
  1982.             switch(ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
  1983.             {
  1984.                 case 2:    SerialClosed = FALSE;
  1985.                     break;
  1986.  
  1987.                 case 0:    MainTerminated = TRUE;
  1988.                     break;
  1989.             }
  1990.         }
  1991.         else
  1992.         {
  1993.             SerialClosed = FALSE;
  1994.  
  1995.             if(SerialMessage)
  1996.             {
  1997.                 ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  1998.  
  1999.                 SerialMessage = NULL;
  2000.             }
  2001.         }
  2002.     }
  2003.     while(SerialClosed);
  2004. }
  2005.  
  2006.     /* HandleSerial():
  2007.      *
  2008.      *    Handle the data coming in from the serial line.
  2009.      */
  2010.  
  2011. BOOL
  2012. HandleSerial()
  2013. {
  2014.     BOOL MoreData = FALSE;
  2015.  
  2016.     if(ReadPort && !ReleaseSerial && Status != STATUS_HOLDING)
  2017.     {
  2018.         if(HostReadBuffer)
  2019.         {
  2020.             LONG Length = XProtocolHostMon(XprIO,HostReadBuffer,0,SerialBufferSize);
  2021.  
  2022.             if(Translate_CR_LF)
  2023.                 Length = (* Translate_CR_LF)(HostReadBuffer,Length);
  2024.  
  2025.             if(Length)
  2026.             {
  2027.                 if(Marking)
  2028.                     DropMarker();
  2029.  
  2030.                 ConProcess(HostReadBuffer,Length);
  2031.  
  2032.                 if(Status == STATUS_HOLDING)
  2033.                     return(FALSE);
  2034.             }
  2035.  
  2036.             MoreData = TRUE;
  2037.         }
  2038.  
  2039.         if(DataHold)
  2040.         {
  2041.             register STRPTR    Data    = DataHold;
  2042.             register LONG    Size    = DataSize;
  2043.  
  2044.             DataHold = NULL;
  2045.  
  2046.             if(Marking)
  2047.                 DropMarker();
  2048.  
  2049.             (* ConTransfer)(Data,Size);
  2050.  
  2051.             MoreData = TRUE;
  2052.  
  2053.             RestartSerial();
  2054.  
  2055.             return(MoreData);
  2056.         }
  2057.  
  2058.             /* Any news? */
  2059.  
  2060.         if(CheckSerialRead())
  2061.         {
  2062.             MoreData = TRUE;
  2063.  
  2064.             if(!WaitSerialRead())
  2065.             {
  2066.                 if(Marking)
  2067.                     DropMarker();
  2068.  
  2069.                 BytesIn++;
  2070.  
  2071.                 if(Translate_CR_LF)
  2072.                 {
  2073.                     register LONG Size = (* Translate_CR_LF)(ReadBuffer,1);
  2074.  
  2075.                     if(Size)
  2076.                         (* ConTransfer)(ReadBuffer,Size);
  2077.                 }
  2078.                 else
  2079.                     (* ConTransfer)(ReadBuffer,1);
  2080.  
  2081.                 if(Status != STATUS_HOLDING && !DataHold)
  2082.                 {
  2083.                     ULONG Length;
  2084.  
  2085.                         /* Check how many bytes are still in
  2086.                          * the serial buffer.
  2087.                          */
  2088.  
  2089.                     if(Length = GetSerialWaiting())
  2090.                     {
  2091.                         ULONG Max = SerialBufferSize;
  2092.  
  2093.                         if(Max > Config -> SerialConfig -> Quantum)
  2094.                             Max = Config -> SerialConfig -> Quantum;
  2095.  
  2096.                         if(Length > Max)
  2097.                             Length = Max;
  2098.  
  2099.                         if(!DoSerialRead(ReadBuffer,Length))
  2100.                         {
  2101.                             BytesIn += Length;
  2102.  
  2103.                             if(Translate_CR_LF)
  2104.                             {
  2105.                                 if(Length = (* Translate_CR_LF)(ReadBuffer,Length))
  2106.                                     (* ConTransfer)(ReadBuffer,Length);
  2107.                             }
  2108.                             else
  2109.                                 (* ConTransfer)(ReadBuffer,Length);
  2110.                         }
  2111.                     }
  2112.                 }
  2113.             }
  2114.  
  2115.             if(DataHold)
  2116.                 ClrSignal(SIG_SERIAL);
  2117.             else
  2118.                 RestartSerial();
  2119.         }
  2120.     }
  2121.  
  2122.     return(MoreData);
  2123. }
  2124.